<template>
	<div class="model-view">
		<div ref="model" class="model"></div>
		<div class="progress">
			<div class="mask"></div>
			<div class="loading">
				<div class="trends"></div>
			</div>
		</div>
	</div>
</template>

<script>
import * as THREE from '@/assets/vendor/three/build/three.module.js'
import { OrbitControls } from '@/assets/vendor/three/examples/jsm/controls/OrbitControls.js'
import { DDSLoader } from '@/assets/vendor/three/examples/jsm/loaders/DDSLoader.js'
import { MTLLoader } from '@/assets/vendor/three/examples/jsm/loaders/MTLLoader.js'
import { OBJLoader } from '@/assets/vendor/three/examples/jsm/loaders/OBJLoader.js'

export default {
	props: {
		MTLLoaderPath: {
			type: String,
			default: ''
		},
		MTLLoaderFile: {
			type: String,
			default: ''
		},
		OBJLoaderPath: {
			type: String,
			default: ''
		},
		OBJLoaderFile: {
			type: String,
			default: ''
		}
	},

  data () {
    return {

    }
  },

	mounted () {
		this.init()
	},

  methods: {
    init () {
			let $this = this
			let camera, scene, renderer;
			let mouseX = 0, mouseY = 0;
			let rect = this.$el.getBoundingClientRect()
			let width = rect.width, height = rect.height || (window.innerHeight - 80) || 640
			let windowHalfX = width / 2;
			let windowHalfY = height / 2;

			init();
			animate();
			let model

			function init() {
				let container = $this.$refs.model;

				// scene
				scene = new THREE.Scene();
				scene.background = new THREE.Color( 0x999999 );   //背景颜色
				const ambientLight = new THREE.AmbientLight( 0xffffff, 0.3 );   //环境光
				scene.add( ambientLight );

				var light = new THREE.DirectionalLight(0xffffff,0.3);
				light.position.set(500,500,8000);
				light.castShadow = true;
				light.shadow.camera.top = 2;
				light.shadow.camera.bottom = - 2;
				light.shadow.camera.left = - 2;
				light.shadow.camera.right = 2;
				light.shadow.camera.near = 0.1;
				light.shadow.camera.far = 40;
				scene.add(light);

				camera = new THREE.PerspectiveCamera( 45, width / height, 1, 20000 );
				camera.position.set( 0, 0, 3000 );
				scene.add( camera );

				// model
				const onProgress = function ( xhr ) {
					if ( xhr.lengthComputable ) {
						var percentComplete = xhr.loaded / xhr.total * 100;
						play(Math.round( percentComplete, 2 ))
					}
				};

				const onError = function (xhr) { };
				const manager = new THREE.LoadingManager();
				manager.addHandler( /\.dds$/i, new DDSLoader() );

				new MTLLoader( manager )
					.setPath( $this.MTLLoaderPath )
					.load( $this.MTLLoaderFile, function ( materials ) {
						materials.preload();
						new OBJLoader( manager )
							.setMaterials( materials )
							.setPath( $this.OBJLoaderPath )
							.load( $this.OBJLoaderFile, function ( object ) {
								//object.children[0].geometry.computeBoundingBox();
								//object.children[0].geometry.center();
								object.traverse(function(child) {
									if (child instanceof THREE.Mesh) {
										if ( child.material['id'] == undefined ) {
											for(var i = 0; i < child.material.length; i++){
												let material = child.material[i]
												material.side = THREE.DoubleSide;
												// 消除裂纹
												material.map.magFilter = THREE.LinearFilter;
            						material.map.minFilter = THREE.LinearFilter;
											}
										} else {
											let material = child.material
											material.side = THREE.DoubleSide;
											// 消除裂纹
											material.map.magFilter = THREE.LinearFilter;
            					material.map.minFilter = THREE.LinearFilter;
										}
									}
								});
								object.position.y = - 95;
								scene.add( object );
								model = object
								// 计算模型的边界盒
								const box = new THREE.Box3().setFromObject(model);
								// 计算模型中心点
								const center = new THREE.Vector3();
								box.getCenter(center);
								// 计算相机位置
								const sphere = box.getBoundingSphere(new THREE.Sphere());
								const maxDimension = Math.max(sphere.radius, ...box.getSize().toArray());
								camera.position.copy(center).add(new THREE.Vector3(0, 0, maxDimension * 2));
							}, onProgress, onError );
					} );

				renderer = new THREE.WebGLRenderer({antialias:true,alpha:true});
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( width, height );
				// renderer.setFaceCulling(THREE.CullFaceNone, THREE.FrontFaceDirectionCCW);
				container.appendChild( renderer.domElement );

				const controls = new OrbitControls( camera, renderer.domElement );
				controls.addEventListener( 'change', render ); // use if there is no animation loop
				controls.minDistance = 0.01;
				controls.maxDistance = 10000;
				controls.target.set( 0, 2, 0);
				controls.enablePan = true;
				controls.update();



				//document.addEventListener( 'mousemove', onDocumentMouseMove );
				window.addEventListener( 'resize', onWindowResize );
			}

			function onWindowResize() {
				windowHalfX = width / 2;
				windowHalfY = height / 2;
				camera.aspect = width / height;
				camera.updateProjectionMatrix();
				renderer.setSize( width, height );
			}

			function onDocumentMouseMove( event ) {
				mouseX = ( event.clientX - windowHalfX ) / 2;
				mouseY = ( event.clientY - windowHalfY ) / 2;
			}

			function animate() {
				requestAnimationFrame( animate );
				render();
			}

			function render() {
				// camera.position.x += ( mouseX - camera.position.x ) * .05;
				// camera.position.y += ( - mouseY - camera.position.y ) * .05;
				camera.lookAt( scene.position );
				//var pLocal = new THREE.Vector3( 0, 0, -1 );
				//var pWorld = pLocal.applyMatrix4( camera.matrixWorld );
				//var dir = pWorld.sub( camera.position ).normalize();
				//console.log({'x':camera.position.x,'y':camera.position.y,'z':camera.position.z});
				renderer.render( scene, camera );
				//console.log(camera.position);

			}

			let $el = this.$el
			function play(a){
				$el.querySelectorAll(".trends")[0].style.width = a + "%";
				if(a < 100 ){
					$el.querySelector(".progress").style.display = "block";
				}else{
					$el.querySelector(".progress").style.display = "none";
				}
			}

			document.addEventListener('mouseover',function(){
				// console.log(window.parent.lastTime);
        window.parent.lastTime = new Date().getTime();
		 	})
    }
  }
}
</script>

<style lang="less" scoped>
.model-view {
	position: relative;
}
/* 进度条 */
.progress {
	position: absolute;
	left: 0;
	top: 0;
	width:  100%;
	height: 100%;
}
.progress .mask{
	position: absolute;
	left: 0;
	top: 0;
	width:  100%;
	height: 100%;
	background:  rgba(0,0,0,0.2);
	z-index: 99;
}
.progress .loading{
	width: 30em;
	height: 1em;
	background: #fff;
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	z-index: 100;
	border-radius: 1em;
}
.progress .trends{
	width: 0;
	height: 100%;
	background: green;
	box-shadow: 1px 1px 10px green;
	border-radius: 1em;
}
</style>
